import json
import os
import time

from flask_pymongo import MongoClient
from pydantic import BaseModel


class Datas(BaseModel):
    time: float  # 时间戳
    h: int  # 小时
    m: int  # 分钟
    sbp: float  # 收缩压
    dbp: float  # 舒张压
    device_id: str  # 设备ID


class Tickets(BaseModel):
    device_id: str  # 设备ID
    ticket: str  # ticket


class Binds(BaseModel):
    device_id: str  # 设备ID
    wechat: str  # 微信id
    web: str  # web id
    bind_time: float  # 绑定时间
    unbind: bool = False  # 是否解绑


# 获取当前文件路径
base_path = os.path.dirname(__file__)
# 读取配置文件
config_path = os.path.join(base_path, "config.json")
f = open(config_path, "r", encoding="utf-8")
config = json.load(f)
f.close()

# 链接MongoDB
mongo_url = ('mongodb://' +
             config["mongo_user"] + ':' +
             config["mongo_password"] + '@' +
             config["mongo_host"])
client = MongoClient(
    host=mongo_url,
    maxPoolSize=50,  # 最大连接池数量
    connectTimeoutMS=20000,  # 连接超时时间
    socketTimeoutMS=20000,  # 套接字超时时间
)


def init_database():
    """
    初始化数据库
    请注意，MongoDB并不一定需要提前创建数据库，此处的操作是为了方便理解和演示
    此外，该函数也可用于检测MongoDB是否正确安装和配置
    """
    # 选择数据库，数据库名为 blood_pressure
    db = client.blood_pressure
    # 选择blood_pressure数据库中的数据集合，数据集合名为 datas
    data_collection = db.datas
    # 如果没有索引
    if "device_id" not in str(data_collection.index_information()):
        data_collection.create_index("device_id")
    if "time" not in str(data_collection.index_information()):
        data_collection.create_index("time")
    # 选择blood_pressure数据库中的设备ticket数据集合，数据集合名为 tickets
    ticket_collection = db.tickets
    # 如果没有索引
    if "ticket" not in str(ticket_collection.index_information()):
        ticket_collection.create_index("ticket")
    # # 选择绑定集合
    # binding_collection = db.bindings
    # # 如果没有索引
    # if "wechat" not in str(binding_collection.index_information()):
    #     binding_collection.create_index("wechat")


init_database()


def delete_database():
    """
    删除数据库
    """
    input("此操作将删除数据库中所有数据，是否继续？")
    client.drop_database("blood_pressure")
    init_database()


def load_json(file_path):
    """
    读取json文件
    """
    with open(file_path, "r", encoding="utf-8") as f:
        return json.load(f)


def save_json(file_path, data):
    """
    保存json文件
    """
    with open(file_path, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False)


def search_device_id_by_openid(wechat):
    """
    通过微信ID查找设备ID

    """
    db = client.blood_pressure
    binding_collection = db.bindings
    binding = binding_collection.find_one({"wechat": wechat, "unbind": False})
    if binding:
        return binding["device_id"]
    else:
        return None


def bind_device(wechat, device_id):
    """
    绑定设备, 存在wechat则将记录解绑，再绑定新设备
    """
    db = client.blood_pressure
    binding_collection = db.bindings
    # 不要使用one，可能有多个绑定
    binding = binding_collection.find({"wechat": wechat, "unbind": False})
    for b in binding:
        binding_collection.update_one({"_id": b["_id"]}, {"$set": {"unbind": True}})
    binding_collection.insert_one(
        Binds(device_id=device_id, wechat=wechat, bind_time=time.time(), web="", unbind=False).model_dump())


def search_data_by_device_and_date(device_id, date):
    """
    通过设备ID和时间范围查找数据
    date: 日期，格式为"2021-01-01"
    """
    db = client.blood_pressure
    data_collection = db.datas
    start = date + " 00:00:00"
    end = date + " 23:59:59"
    # 转换为时间戳
    start = int(time.mktime(time.strptime(start, "%Y-%m-%d %H:%M:%S")))
    end = int(time.mktime(time.strptime(end, "%Y-%m-%d %H:%M:%S")))
    result = data_collection.find(
        {"device_id": device_id, "time": {"$gte": start, "$lte": end}},
        {"_id": 0}
    )  # 排除 _id 字段
    return list(result)

# if __name__ == "__main__":
#     delete_database()
